package com.itstherules.jmsunit;

import java.util.LinkedList;
import java.util.List;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;

import com.itstherules.jmsunit.JmsCleaner;
import com.itstherules.jmsunit.JmsReceiver;
import com.itstherules.jmsunit.JmsSender;
import com.itstherules.jmsunit.header.HeadersPopulator;
import com.itstherules.jmsunit.headers.JmsHeadersDefinition;
import com.itstherules.jmsunit.managers.QueueManager;
import com.itstherules.jmsunit.mock.SendingInformation;
import com.itstherules.jmsunit.mock.store.Store;

public abstract class JmsMock {

	private static final long timeout = 3000;
	
	protected List<Store> mall = new LinkedList<Store>();
	protected final QueueManager queueManager;

	public JmsMock(QueueManager queueManager) throws Exception {
		this.queueManager = queueManager;
	}
	
	public void cleanQueues(String... queues) throws Exception {
		for (String queue : queues) {
			JmsCleaner cleaner = new JmsClient(queueManager, queue);
			cleaner.clean();
		}
	}

	protected void send(Store store) throws Exception {
		if(store.requiresAReply()) {
			SendingInformation info = store.getSendReplyInformation();
			JmsSender client = new JmsClient(queueManager, info.getQueue());
			TextMessage message = queueManager.getTextMessage(info.getMessage());
			JmsHeadersDefinition definition = info.getDefinition();
			new HeadersPopulator(queueManager).populate(definition, message);
			
			if (store.getCorrelationId() != null) {
				message.setJMSCorrelationID(store.getCorrelationId());
			}
			
			client.send(message);
		}
	}
	

	protected Message receive(Store store, String messageId) throws JMSException, AssertionError {
		String queue = store.getThrough();
		JmsReceiver client = new JmsClient(queueManager, queue);
		Message message = client.receive(timeout, messageId);
		if(message == null) {
			throw new AssertionError("Unable to consume message from queue " + queue + ", timed out after " + timeout / 1000 + " seconds");
		}
		store.setCorrelationId(message.getJMSMessageID());
		return message;
	}

	protected Message receive(Store store) throws JMSException, AssertionError {
		String queue = store.getThrough();
		JmsReceiver client = new JmsClient(queueManager, queue);
		Message message = client.receive(timeout);
		if(message == null){
			throw new AssertionError("Unable to consume message from queue " + queue + ", timed out after " + timeout / 1000 + " seconds");
		}
		store.setCorrelationId(message.getJMSMessageID());
		return message;
	}

	@Override
	public String toString() {
		String separator = System.getProperty("line.separator");
		StringBuffer buffer = new StringBuffer();
		for (Store store : mall) {
			buffer.append("[");
			buffer.append(separator);
			buffer.append(store.toString());
			buffer.append("]");
			buffer.append(separator);
			buffer.append(separator);
		}
		return buffer.toString();
	}
}